package com.css.fxfzdzzh.modules.tifData.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzdzzh.base.attachment.entity.AttachmentInfoEntity;
import com.css.fxfzdzzh.base.attachment.service.AttachmentInfoService;
import com.css.fxfzdzzh.base.response.RestResponse;
import com.css.fxfzdzzh.modules.eqLandslide.count.entity.Slope;
import com.css.fxfzdzzh.modules.eqLandslide.lawAnalysis.repository.LawAnalysisRepository;
import com.css.fxfzdzzh.modules.hypergraph.service.HypergraphService;
import com.css.fxfzdzzh.modules.tifData.param.AspectTifComputeParam;
import com.css.fxfzdzzh.modules.tifData.param.SlopeTifComputeParam;
import com.css.fxfzdzzh.modules.tifData.service.ElevationMapService;
import com.css.fxfzdzzh.util.PlatformObjectUtils;
import com.css.fxfzdzzh.util.StringUtils;
import com.css.fxfzdzzh.util.UUIDGenerator;
import lombok.extern.slf4j.Slf4j;
import org.gdal.gdal.*;
import org.gdal.gdalconst.gdalconstConstants;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.opengis.filter.Filter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author zyt
 * @Date: 2022/10/04
 */
@Service
@Slf4j
public class ElevationMapServiceImpl implements ElevationMapService {
    @Resource
    JdbcTemplate jdbcTemplate;
    @Resource
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired
    private AttachmentInfoService attachmentInfoService;

    @Resource
    LawAnalysisRepository lawAnalysisRepository;

    @Resource
    HypergraphService hypergraphService;

    @Value("${image.localDir}")
    private String localDir;

    private static String strWKTMercator = "PROJCS[\"CGCS2000_GK_Zone_20\",GEOGCS[\"GCS_China_Geodetic_Coordinate_System_2000\",DATUM[\"D_China_2000\",SPHEROID[\"CGCS2000\",6378137.0,298.257222101]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gauss_Kruger\"],PARAMETER[\"False_Easting\",20500000.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",117.0],PARAMETER[\"Scale_Factor\",1.0],PARAMETER[\"Latitude_Of_Origin\",0.0],UNIT[\"Meter\",1.0]]";


    /**
     * 数据源
     * 10.19.41.111
     */
    @Value("${spring.datasource.url}")
    private String url = "";
    @Value("${spring.datasource.username}")
    private String name = "";
    @Value("${spring.datasource.password}")
    private String pwd = "";

    /**
     * 获取数据库连接
     * SQL语句
     */
    private Connection getConnection() throws Exception {
        //Class.forName("com.mysql.cj.jdbc.Driver");
        Class.forName("org.postgresql.Driver");
        Connection conn = DriverManager.getConnection(url, name, pwd);
        return conn;
    }

    // @Value("E:/MapData/demTif/")
    @Value("${dem.demFilePath}")
    String demFilePath;
    @Value("${dem.demFileDir}")
    String demFileDir;
    @Value("${dem.demFileFolder}")
    String demFileFolder;

    //读取坡度tif文件发布超图图层
    @Override
    public List<String> importSlopeTif(String tifFileName) {
        List<String> returnMsgList = new ArrayList<>();
        System.out.println("坡度tif文件名：" + tifFileName);
        String slopeFilePath = demFilePath + tifFileName + ".tif";
        //校验是否为2000坐标系
        if (!(checkCGCS2000Tif(slopeFilePath))) {
            log.info(new Date() + "-----------校验失败.请上传正确的CGCS2000坐标系数据.tif文件.");
            returnMsgList.add("校验失败.请上传正确的CGCS2000坐标系数据.tif文件");
            return returnMsgList;
        }
        //使用超图处理自动化工具导入坡度文件发布
        Map<String, Object> map = new HashMap<>();
        map.put("type", "importSlopeTif");
        map.put("layerName", tifFileName);//坡度数据集名称
        map.put("filePath", demFilePath + tifFileName + ".tif");//坡度文件路径
        RestResponse restResponse = hypergraphService.getServerToken(map);
        if (restResponse.getData() != null) {
            JSONObject json = (JSONObject) JSON.toJSON(restResponse.getData());
            String result = (String) json.get("result");
            if (result.equals("获取成功！")) {
                returnMsgList.add("生成成功");
                returnMsgList.add(slopeFilePath);
                //获取坡度tif文件全部数据长度
                int dataLength = getPdDataLengthByTIF(slopeFilePath);
                returnMsgList.add(String.valueOf(dataLength));
            }
        } else {
            returnMsgList.add(restResponse.getCode() + ": " + restResponse.getMessage());
        }
        return returnMsgList;
    }

    //根据上传的坡向tif文件发布超图图层
    @Override
    public List<String> importAspectTif(String tifFileName) {
        List<String> returnMsgList = new ArrayList<>();
        System.out.println("坡向tif文件名：" + tifFileName);
        String aspectFilePath = demFilePath + tifFileName + ".tif";
        //校验是否为2000坐标系
        if (!(checkCGCS2000Tif(aspectFilePath))) {
            log.info(new Date() + "-----------校验失败.请上传正确的CGCS2000坐标系数据.tif文件.");
            returnMsgList.add("校验失败.请上传正确的CGCS2000坐标系数据.tif文件");
            return returnMsgList;
        }
        //使用超图处理自动化工具导入坡向文件发布
        Map<String, Object> map = new HashMap<>();
        map.put("type", "importAspectTif");
        map.put("layerName", tifFileName);//坡向数据集名称
        map.put("filePath", demFilePath + tifFileName + ".tif");//坡向文件路径
        RestResponse restResponse = hypergraphService.getServerToken(map);
        if (restResponse.getData() != null) {
            JSONObject json = (JSONObject) JSON.toJSON(restResponse.getData());
            String result = (String) json.get("result");
            if (result.equals("获取成功！")) {
                returnMsgList.add("生成成功");
                returnMsgList.add(aspectFilePath);
                //获取坡向tif文件全部数据长度
                int dataLength = getPxDataLengthByTIF(aspectFilePath);
                returnMsgList.add(String.valueOf(dataLength));
            }
        } else {
            returnMsgList.add(restResponse.getCode() + ": " + restResponse.getMessage());
        }
        return returnMsgList;
    }

    //读取DEM高程tif文件，计算坡度，保存tif文件
    @Override
    public List<String> computeSlopeTif(SlopeTifComputeParam slopeTifComputeParam) {
        List<String> returnMsgList = new ArrayList<>();
        String filePath = slopeTifComputeParam.getDemTifFilePath();//DEM高程tif文件路径
        System.out.println("路径：" + filePath);
        String[] split = filePath.split("/");
        String demFileName = split[split.length - 1].split("\\.")[0];
        String currTime = System.currentTimeMillis() + "";
        String fileName = "坡度_" + currTime;
        String slopeFilePath = demFilePath + fileName + ".tif";
        //使用超图处理自动化工具生成坡度
        Map<String, Object> map = new HashMap<>();
        map.put("type", "slopeTif");
        map.put("teraName", demFileName);//高程数据集名称
        map.put("layerName", fileName);//坡度数据集名称
        map.put("filePath", demFilePath + fileName + ".tif");//坡度文件路径
        RestResponse restResponse = hypergraphService.getServerToken(map);
        if (restResponse.getData() != null) {
            JSONObject json = (JSONObject) JSON.toJSON(restResponse.getData());
            String result = (String) json.get("result");
            if (result.equals("获取成功！")) {
                returnMsgList.add("生成成功");
                //保存tif文件到附件表
                String attachId = saveTifFileAttach(fileName);
                returnMsgList.add(attachId);
                //获取坡度tif文件全部数据长度
                int dataLength = getPdDataLengthByTIF(slopeFilePath);
                returnMsgList.add(String.valueOf(dataLength));
            }
        } else {
            returnMsgList.add(restResponse.getCode() + ": " + restResponse.getMessage());
        }
        return returnMsgList;
    }

    //读取DEM高程tif文件，计算坡向，保存tif文件
    @Override
    public List<String> computeAspectTif(AspectTifComputeParam aspectTifComputeParam) {
        List<String> returnMsgList = new ArrayList<>();
        String filePath = aspectTifComputeParam.getDemTifFilePath();//DEM高程tif文件路径
        //生产环境：/data/sjxt/shape/2023/07/26/高程_四川雅江县_裁剪_202307261451_1690354305482.tif
//        String[] split = filePath.split("/");
//        String demFileName = split[split.length - 1].split("\\.")[0];
        String[] split = filePath.split("\\\\");
        String[] split1 = split[split.length - 1].split("/");
        String demFileName = split1[split1.length - 1].split("\\.")[0];
        if (demFileName.contains(".tif")) {
            demFileName = demFileName.split(".tif")[0];
        }
        String currTime = System.currentTimeMillis() + "";
        String fileName = "坡向_" + currTime;
        String aspectFilePath = demFilePath + fileName + ".tif";

        //使用超图处理自动化工具生成坡向
        Map<String, Object> map = new HashMap<>();
        map.put("type", "aspectTif");
        map.put("teraName", demFileName);//高程数据集名称
        map.put("layerName", fileName);//坡向数据集名称
        map.put("filePath", demFilePath + fileName + ".tif");//坡向文件路径
        RestResponse restResponse = hypergraphService.getServerToken(map);
        if (restResponse.getData() != null) {
            JSONObject json = (JSONObject) JSON.toJSON(restResponse.getData());
            String result = (String) json.get("result");
            if (result.equals("获取成功！")) {
                returnMsgList.add("生成成功");
                //保存tif文件到附件表
                String attachId = saveTifFileAttach(fileName);
                returnMsgList.add(attachId);
                //获取坡向tif文件全部数据长度
                int dataLength = getPxDataLengthByTIF(aspectFilePath);
                returnMsgList.add(String.valueOf(dataLength));
            }
        }
        return returnMsgList;
    }

    //校验Tif文件是否为2000坐标系
    public boolean checkCGCS2000Tif(String path) {
        String name = "";
//        gdal.AllRegister();
        Dataset dataset = gdal.Open(path, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return false;
        name = dataset.GetProjection();//获取地理信息
        dataset.delete();
//        gdal.GDALDestroyDriverManager();
        /*if (name.indexOf("CGCS2000") != -1 || name.indexOf("cgcs2000") != -1 || name.indexOf("Geodetic_Coordinate_System_2000") != -1 ||
                name.indexOf("Geodetic Coordinate System 2000") != -1) return true;*/
        if (name.indexOf("Geodetic_Coordinate_System_2000") != -1 ||
                name.indexOf("Geodetic Coordinate System 2000") != -1) return true;

        return false;
    }

    //保存tif文件到附件表
    public String saveTifFileAttach(String fileName) {
        List<AttachmentInfoEntity> attachmentInfoEntities = new ArrayList<>();
        //构建实体类
        String id = StringUtils.buildPrimaryId();
        AttachmentInfoEntity attachmentInfoEntity = new AttachmentInfoEntity();
        attachmentInfoEntity.setAttachId(id);
        attachmentInfoEntity.setAttachName(fileName);
        attachmentInfoEntity.setAttachPath(demFileFolder + fileName);
        attachmentInfoEntity.setFileDirId(demFileDir);
        attachmentInfoEntity.setIsValid("1");
        attachmentInfoEntity.setIsCompleted("1");
        attachmentInfoEntities.add(attachmentInfoEntity);
        //保存
        int flag = attachmentInfoService.save(attachmentInfoEntities);
        if (flag == 1) {//保存成功
            return id;
        }
        return "";
    }

    //获取坡度tif文件全部数据长度
    public int getPdDataLengthByTIF(String tifFileName) {
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(tifFileName, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return -1;

        Band band = dataset.GetRasterBand(1);

        int xSize = dataset.getRasterXSize();
        int ySize = dataset.getRasterYSize();

        //GeoTransform 的含义：
        //六参数信息
        double[] geoTransform = dataset.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组
        //影像左上角投影坐标
        double[] luCoordinate = new double[2];
        double lon = geoTransform[0];//影像左上角横坐标：对应经度
        double lat = geoTransform[3];//影像左上角纵坐标：对应纬度
        //判断经纬度值是否正常
        if (lon < 0 || lon > 180 || lat < 0 || lat > 180) {
            return 0;
        }

        int count = 0;
        int buf[] = new int[xSize];
        for (int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for (int j = 0; j < xSize; j++) {
                //坡度范围：最小值0，最大值90，无数据值N/A
                if (buf[j] >= 0 && buf[j] <= 90) {
                    count++;
                }
            }
        }
        dataset.delete();
//        gdal.GDALDestroyDriverManager();

        return count;
    }

    //获取坡向tif文件全部数据长度
    public int getPxDataLengthByTIF(String tifFileName) {
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(tifFileName, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return -1;

        Band band = dataset.GetRasterBand(1);

        int xSize = dataset.getRasterXSize();
        int ySize = dataset.getRasterYSize();

        //GeoTransform 的含义：
        //六参数信息
        double[] geoTransform = dataset.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组
        //影像左上角投影坐标
        double[] luCoordinate = new double[2];
        double lon = geoTransform[0];//影像左上角横坐标：对应经度
        double lat = geoTransform[3];//影像左上角纵坐标：对应纬度
        //判断经纬度值是否正常
        if (lon < 0 || lon > 180 || lat < 0 || lat > 180) {
            return 0;
        }

        int count = 0;
        int buf[] = new int[xSize];
        for (int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for (int j = 0; j < xSize; j++) {
                //坡向范围：最小值0，最大值360，无数据值N/A
                if (buf[j] >= 0 && buf[j] <= 360) {
                    count++;
                }
            }
        }
        dataset.delete();
//        gdal.GDALDestroyDriverManager();

        return count;
    }

    //读取坡度tif文件进行坡度分区统计（网格数、面积、占比）
    @Override
    public List<String> countSlopeTif(String filePath) {
        List<String> returnMsgList = new ArrayList<>();
//        filePath = "D:\\static\\demTif\\坡度_1683855831608.tif";
//        filePath = "D:\\static\\demTif\\坐标转换后的四川dem90米.tif";
//        gdal.AllRegister();
        Dataset dataset = gdal.Open(filePath, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) {
            returnMsgList.add("tif文件中无数据");
            return returnMsgList;
        }
        //校验Tif文件是否为2000坐标系
        String name = dataset.GetProjection();//获取地理信息
        if (name.indexOf("CGCS2000") != -1 || name.indexOf("cgcs2000") != -1 || name.indexOf("Geodetic_Coordinate_System_2000") != -1 ||
                name.indexOf("Geodetic Coordinate System 2000") != -1) {
            //
        } else {
            System.out.println(new Date() + "-----------校验失败.请上传基于CGCS2000坐标系的.tif数据文件.");
            returnMsgList.add("校验失败.请上传基于CGCS2000坐标系的.tif数据文件");
            return returnMsgList;
        }

        // 获取EPSG:4490地理坐标的原点坐标信息
        double[] srcTransform = dataset.GetGeoTransform();
        System.out.println("EPSG:4490地理坐标的原点坐标   = " + srcTransform[0] + "," + srcTransform[3]);
        System.out.println("EPSG:4490地理坐标的像素坐标差 = " + srcTransform[1] + "," + srcTransform[5]);
        double srcLon = srcTransform[0];
        //根据经度获取投影坐标--3度带
        int epsg = getEPSGFromLon3(srcLon);
        //根据经度获取投影坐标
        String epsgStr = "EPSG:" + epsg;
        System.out.println("投影坐标 " + epsgStr);
        //栅格投影坐标转换
//        String dest = "D:\\static\\demTif\\坐标投影转换.tif";
        String currTime = System.currentTimeMillis() + "";
        String dest = filePath.split(".tif")[0] + "_坐标投影转换_" + currTime + ".tif";
        Vector<String> options = new Vector<>();
        options.add("-of");//format 输出格式
        options.add("GTiff");
        options.add("-s_srs");//原坐标系统
        options.add("EPSG:4490");
        options.add("-t_srs");//目标坐标系统
//        options.add("EPSG:4523");
        options.add(epsgStr);
        WarpOptions warpOptions = new WarpOptions(options);
        Dataset[] src_array = {dataset};
        Dataset warp = gdal.Warp(dest, src_array, warpOptions);
        // 获取栅格投影坐标转换的原点坐标信息
        double[] warpTransform = warp.GetGeoTransform();
        System.out.println("warp原点坐标   = " + warpTransform[0] + "," + warpTransform[3]);
        System.out.println("warp像素坐标差 = " + warpTransform[1] + "," + warpTransform[5]);

        //读取投影后的栅格数据
        Band band = warp.GetRasterBand(1);

        int xSize = warp.getRasterXSize();
        int ySize = warp.getRasterYSize();

//        int bandCount = warp.getRasterCount();
//        System.out.println("bandCount:"+bandCount);
//        int width = band.getXSize();
//        int height = band.getYSize();
//        System.out.println("width:" + width);
//        System.out.println("height:" + height);
//        int blockX = band.GetBlockXSize();
//        int blockY = band.GetBlockYSize();
//        System.out.println("blockX:" + blockX);
//        System.out.println("blockY:" + blockY);

        //GeoTransform 的含义：
        //六参数信息
        double[] geoTransform = warp.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组

        //统计网格个数
        int count = 0;//总数
        int count0 = 0;//[0,10]
        int count1 = 0;//(10,20]
        int count2 = 0;//(20,30]
        int count3 = 0;//(30,40]
        int count4 = 0;//(40,50]
        int count5 = 0;//(50,60]
        int count6 = 0;//(60,70]
        int count7 = 0;//(70,80]
        int count8 = 0;//(80,90]

        int buf[] = new int[xSize];
        for (int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for (int j = 0; j < xSize; j++) {
                //坡度范围：最小值0，最大值90，无数据值N/A
                if (buf[j] >= 0 && buf[j] <= 90) {
                    count++;
                    if (buf[j] >= 0 && buf[j] <= 10) {
                        count0++;
                    } else if (buf[j] > 10 && buf[j] <= 20) {
                        count1++;
                    } else if (buf[j] > 20 && buf[j] <= 30) {
                        count2++;
                    } else if (buf[j] > 30 && buf[j] <= 40) {
                        count3++;
                    } else if (buf[j] > 40 && buf[j] <= 50) {
                        count4++;
                    } else if (buf[j] > 50 && buf[j] <= 60) {
                        count5++;
                    } else if (buf[j] > 60 && buf[j] <= 70) {
                        count6++;
                    } else if (buf[j] > 70 && buf[j] <= 80) {
                        count7++;
                    } else if (buf[j] > 80 && buf[j] <= 90) {
                        count8++;
                    }
                }
            }
        }

        dataset.delete();
        warp.delete();
//        gdal.GDALDestroyDriverManager();

        //统计网格个数
        String countString = count + "," + count0 + "," + count1 + "," + count2 + "," + count3 + "," + count4
                + "," + count5 + "," + count6 + "," + count7 + "," + count8;
        //经度差值长度（米）
        double lonDiffMeter = geoTransform[1];
        //纬度差值长度（米）
        double latDiffMeter = Math.abs(geoTransform[5]);

        //单个栅格网格面积（平方公里）
        double area = lonDiffMeter * latDiffMeter / 1000000;
        //统计面积（平方公里）
        String areaString = area * count + "," + area * count0 + "," + area * count1 + "," + area * count2 + "," + area * count3 + "," + area * count4
                + "," + area * count5 + "," + area * count6 + "," + area * count7 + "," + area * count8;

        returnMsgList.add("统计成功");
        returnMsgList.add(countString);//统计网格个数
        returnMsgList.add(areaString);//统计面积（平方公里）
        returnMsgList.add(String.valueOf(area));//单个栅格网格面积（平方公里）

        return returnMsgList;
    }

    //获取任务范围extent经纬度
    @Override
    public List<Double> getTaskExtent(String taskId) {
        List<Double> lonlatList = new ArrayList<Double>();
        String sql = "select st_extent(geom) from dzzh_task where dt_id=?";
        String boxExtent = jdbcTemplate.queryForObject(sql, String.class, taskId);
        if (PlatformObjectUtils.isNotEmpty(boxExtent) && boxExtent.indexOf("BOX(") == 0) {
            String box = boxExtent.replace("BOX(", "").replace(")", "");
            String[] lonlatArr = box.split(",");
            String[] minLonLat = lonlatArr[0].split(" ");
            String[] maxLonLat = lonlatArr[1].split(" ");
            if (minLonLat.length == 2 && maxLonLat.length == 2) {
                lonlatList.add(Double.valueOf(minLonLat[0]));//最小经度
                lonlatList.add(Double.valueOf(minLonLat[1]));//最小纬度
                lonlatList.add(Double.valueOf(maxLonLat[0]));//最大经度
                lonlatList.add(Double.valueOf(maxLonLat[1]));//最大纬度
            }
        }

        return lonlatList;
    }

    //获取任务范围中心点经纬度
    @Override
    public List<String> getTaskCenterLonLat(String taskId) {
        List<String> centerLonLat = new ArrayList<>();
        if (PlatformObjectUtils.isNotEmpty(taskId)) {
            String sql = "SELECT st_astext(st_centroid(geom)) from dzzh_task where dt_id=?";
            String centerPoint = jdbcTemplate.queryForObject(sql, String.class, taskId);
            if (PlatformObjectUtils.isNotEmpty(centerPoint) && centerPoint.indexOf("POINT(") != -1) {
                String lonlatStr = centerPoint.replace("POINT(", "").replace(")", "");
                String[] lonlat = lonlatStr.split(" ");
                if (lonlat.length == 2) {
                    centerLonLat.add(lonlat[0]);//经度
                    centerLonLat.add(lonlat[1]);//纬度
                }
            }
        }

        return centerLonLat;
    }

    //根据任务ID获取投影坐标EPSG
    @Override
    public int getEPSGFromTask(String taskId) {
        int epsg = 0;
        if (PlatformObjectUtils.isNotEmpty(taskId)) {
            //获取任务范围extent经纬度
            List<Double> lonlatList = getTaskExtent(taskId);
            if (lonlatList.size() == 4) {
                double minLon = lonlatList.get(0);//最小经度
                double minLat = lonlatList.get(1);//最小纬度
                double maxLon = lonlatList.get(2);//最大经度
                double maxLat = lonlatList.get(3);//最大纬度
                double temp = (maxLon - minLon) / 3;
                int minEpsg = 0;
                int maxEpsg = 0;
                int type = 6;//投影带类型3度带|6度带
                if (temp > 1) {//根据经度获取投影坐标--6度带
                    type = 6;
                    minEpsg = getEPSGFromLon6(minLon);
                    maxEpsg = getEPSGFromLon6(maxLon);
                } else {//根据经度获取投影坐标--3度带
                    type = 3;
                    minEpsg = getEPSGFromLon3(minLon);
                    maxEpsg = getEPSGFromLon3(maxLon);
                }
                if (minEpsg > 0 && maxEpsg > 0) {
                    if (minEpsg == maxEpsg) {//同一投影带
                        epsg = minEpsg;
                    } else {//不同投影带
                        //获取中心点所在的投影带
                        List<String> centerLonLat = getTaskCenterLonLat(taskId);
                        if (centerLonLat.size() == 2) {
                            //中心点经度
                            double centerLon = Double.valueOf(centerLonLat.get(0));
                            //根据经度获取投影坐标--6度带
                            epsg = getEPSGFromLon6(centerLon);
                        }
                    }
                }
            }
        }

        return epsg;
    }

    //根据空间数据wkt获取投影坐标EPSG
    @Override
    public int getEPSGFromGeomText(String geomText) {
        int epsg = 0;
        if (PlatformObjectUtils.isNotEmpty(geomText)) {
            //获取区域范围extent经纬度
            List<Double> lonlatList = getGeomExtentLonLat(geomText);
            if (lonlatList.size() == 4) {
                double minLon = lonlatList.get(0);//最小经度
                double minLat = lonlatList.get(1);//最小纬度
                double maxLon = lonlatList.get(2);//最大经度
                double maxLat = lonlatList.get(3);//最大纬度
                double temp = (maxLon - minLon) / 3;
                int minEpsg = 0;
                int maxEpsg = 0;
                int type = 6;//投影带类型3度带|6度带
                if (temp > 1) {//根据经度获取投影坐标--6度带
                    type = 6;
                    minEpsg = getEPSGFromLon6(minLon);
                    maxEpsg = getEPSGFromLon6(maxLon);
                } else {//根据经度获取投影坐标--3度带
                    type = 3;
                    minEpsg = getEPSGFromLon3(minLon);
                    maxEpsg = getEPSGFromLon3(maxLon);
                }
                if (minEpsg > 0 && maxEpsg > 0) {
                    if (minEpsg == maxEpsg) {//同一投影带
                        epsg = minEpsg;
                    } else {//不同投影带
                        //获取中心点所在的投影带
                        List<String> centerLonLat = getCenterLonLat(geomText);
                        if (centerLonLat.size() == 2) {
                            //中心点经度
                            double centerLon = Double.valueOf(centerLonLat.get(0));
                            //根据经度获取投影坐标--6度带
                            epsg = getEPSGFromLon6(centerLon);
                        }
                    }
                }
            }
        }

        return epsg;
    }

    //获取中心点经纬度
    @Override
    public List<String> getCenterLonLat(String geomText) {
        List<String> centerLonLat = new ArrayList<>();
        if (PlatformObjectUtils.isNotEmpty(geomText)) {
            String sql = "SELECT st_astext(st_centroid(st_geometryfromtext(?,4490)))";
            String centerPoint = jdbcTemplate.queryForObject(sql, String.class, geomText);
            if (PlatformObjectUtils.isNotEmpty(centerPoint) && centerPoint.indexOf("POINT(") != -1) {
                String lonlatStr = centerPoint.replace("POINT(", "").replace(")", "");
                String[] lonlat = lonlatStr.split(" ");
                if (lonlat.length == 2) {
                    centerLonLat.add(lonlat[0]);//经度
                    centerLonLat.add(lonlat[1]);//纬度
                }
            }
        }

        return centerLonLat;
    }

    //按投影带查询空间数据长度（米）
    @Override
    public double getLengthByGeomText(String geomText,String epsgType){
        double length = 0;
        if(epsgType.equals("3度带")){
            String sql = "select st_length(st_transform(st_geomfromtext('"+geomText+"',4490)," +
                    "(floor((st_x(st_centroid(st_geomfromtext('"+geomText+"',4490)))-73.5)/3)-20+4554)::int4))";
            length = jdbcTemplate.queryForObject(sql, Double.class, geomText);
        }else if(epsgType.equals("6度带")){
            String sql = "select st_length(st_transform(st_geomfromtext('"+geomText+"',4490)," +
                    "(floor((st_x(st_centroid(st_geomfromtext('"+geomText+"',4490)))-72)/6)-10+4512)::int4))";
            length = jdbcTemplate.queryForObject(sql, Double.class, geomText);
        }
        return length;
    }

    //3°带中，中央子午线=带号×3
    //根据经度获取投影坐标--3度带
    @Override
    public int getEPSGFromLon3(double srcLon) {
        int epsg = 0;
        int index = 0;
        //4534--CGCS2000_3_Degree_GK_CM_75E--中央子午线75E，带号25
        double startLon = 75 - 1.5;
        //4554--CGCS2000_3_Degree_GK_CM_135E--中央子午线135E，带号45
        double endLon = 135 + 1.5;
        boolean bool = true;
        while (bool) {
            if (srcLon >= startLon && srcLon < (startLon + 3)) {
                epsg = 4534 + index;
                bool = false;
            } else if (srcLon < startLon || srcLon > endLon) {
                epsg = 0;
                bool = false;
            } else {
                index++;
                startLon += 3;
            }
        }

        return epsg;
    }

    //6°带中，中央子午线=带号×6-3
    //根据经度获取投影坐标--6度带
    @Override
    public int getEPSGFromLon6(double srcLon) {
        int epsg = 0;
        int index = 0;
        //4502--CGCS2000_GK_CM_75E--中央子午线75E，带号13
        double startLon = 75 - 3;
        //4512--CGCS2000_GK_CM_135E--中央子午线135E，带号23
        double endLon = 135 + 3;
        boolean bool = true;
        while (bool) {
            if (srcLon >= startLon && srcLon < (startLon + 6)) {
                epsg = 4502 + index;
                bool = false;
            } else if (srcLon < startLon || srcLon > endLon) {
                epsg = 0;
                bool = false;
            } else {
                index++;
                startLon += 6;
            }
        }

        return epsg;
    }

    //根据区域投影到6度带或3度带，计算投影面积之和（平方公里)
    @Override
    public BigDecimal getAreaByGeomEpsgCount(String geomText) {
        BigDecimal area = BigDecimal.ZERO;
        //获取区域范围extent经纬度
        List<Double> lonlatList = getGeomExtentLonLat(geomText);
        if (lonlatList.size() == 4) {
            double minLon = lonlatList.get(0);//最小经度
            double minLat = lonlatList.get(1);//最小纬度
            double maxLon = lonlatList.get(2);//最大经度
            double maxLat = lonlatList.get(3);//最大纬度
            double temp = (maxLon - minLon) / 3;
            int minEpsg = 0;
            int maxEpsg = 0;
            int epsg = 0;
            int type = 6;//投影带类型3度带|6度带
            if (temp > 1) {//根据经度获取投影坐标--6度带
                type = 6;
                minEpsg = getEPSGFromLon6(minLon);
                maxEpsg = getEPSGFromLon6(maxLon);
            } else {//根据经度获取投影坐标--3度带
                type = 3;
                minEpsg = getEPSGFromLon3(minLon);
                maxEpsg = getEPSGFromLon3(maxLon);
            }
            if (minEpsg > 0 && maxEpsg > 0) {
                if (minEpsg == maxEpsg) {//同一投影带
                    epsg = minEpsg;
                    //根据投影坐标计算空间数据投影面积
                    area = getAreaByGeomEpsg(geomText, epsg);
                } else {//不同投影带
                    //用投影带分割面
                    List<String> allPolygonList = splitEpsgGeomList(geomText, minEpsg, maxEpsg, type);
                    if (allPolygonList.size() > 0) {
                        for (int i = 0; i < allPolygonList.size(); i++) {
                            epsg = minEpsg + i;
                            String geomTemp = allPolygonList.get(i);
                            //根据投影坐标计算空间数据投影面积
                            BigDecimal areaTemp = getAreaByGeomEpsg(geomTemp, epsg);
                            area = area.add(areaTemp);
                        }
                    }
                }
            }
        }
        if (area.compareTo(BigDecimal.ZERO) > 0) {
            area = area.divide(BigDecimal.valueOf(1000000));//平方公里
        }

        return area;
    }

    //根据投影坐标计算空间数据投影面积
    public BigDecimal getAreaByGeomEpsg(String geomText, int epsg) {
        String sql = "SELECT st_area(ST_Transform(st_geometryfromtext(?,4490)," + epsg + "))";

        return jdbcTemplate.queryForObject(sql, BigDecimal.class, geomText);
    }

    //用投影带分割面
    public List<String> splitEpsgGeomList(String geomText, int minEpsg, int maxEpsg, int type) {
        String lineText = "MULTILINESTRING(";
        if (type == 6) {//6度带
            //4502--CGCS2000_GK_CM_75E--中央子午线75E，带号13
            double startLon = 75 - 3;
            //4512--CGCS2000_GK_CM_135E--中央子午线135E，带号23
            double endLon = 135 + 3;
            int temp = maxEpsg - minEpsg;
            for (int i = 0; i < temp; i++) {
                double lon = (minEpsg - 4502 + i + 1) * 6 + startLon;
                if (i > 0) {
                    lineText += ",";
                }
                lineText += "(" + lon + " 90," + lon + " 0)";
            }
        } else if (type == 3) {//3度带
            //4534--CGCS2000_3_Degree_GK_CM_75E--中央子午线75E，带号25
            double startLon = 75 - 1.5;
            //4554--CGCS2000_3_Degree_GK_CM_135E--中央子午线135E，带号45
            double endLon = 135 + 1.5;
            int temp = maxEpsg - minEpsg;
            for (int i = 0; i < temp; i++) {
                double lon = (minEpsg - 4534 + i + 1) * 3 + startLon;
                if (i > 0) {
                    lineText += ",";
                }
                lineText += "(" + lon + " 90," + lon + " 0)";
            }
        }
        lineText += ")";
        //用线分割面
        List<String> allPolygonList = splitPolygonByLine(geomText, lineText);

        return allPolygonList;
    }

    //用线分割面
    public List<String> splitPolygonByLine(String polygonText, String lineText) {
        List<String> polygonList = new ArrayList<>();
        String sql = "SELECT st_astext(st_split(st_geomfromtext(?,4490),st_geomfromtext(?,4490)))";
        String collection = jdbcTemplate.queryForObject(sql, String.class, polygonText, lineText);
        if (PlatformObjectUtils.isNotEmpty(collection) && collection.indexOf("GEOMETRYCOLLECTION(") == 0) {
            collection = collection.replace("GEOMETRYCOLLECTION(", "");
            collection = collection.substring(0, collection.length() - 1);
            if (collection.contains("POLYGON((")) {
                if (collection.contains(")),POLYGON((")) {//多个
                    String[] temp = collection.split("\\)\\),POLYGON\\(\\(");
                    for (int i = 0; i < temp.length; i++) {
                        if (i == 0) {
                            String polygon = temp[i] + "))";
                            polygonList.add(polygon);
                        } else if (i == (temp.length - 1)) {
                            String polygon = "POLYGON((" + temp[i];
                            polygonList.add(polygon);
                        } else {
                            String polygon = "POLYGON((" + temp[i] + "))";
                            polygonList.add(polygon);
                        }
                    }
                } else {//1个
                    String polygon = collection;
                    polygonList.add(polygon);
                }
            }
        }

        return polygonList;
    }

    //获取区域范围extent经纬度
    @Override
    public List<Double> getGeomExtentLonLat(String geomText) {
        List<Double> lonlatList = new ArrayList<Double>();
        String sql = "select st_extent(st_geomfromtext(?,4490))";
        String boxExtent = jdbcTemplate.queryForObject(sql, String.class, geomText);
        if (PlatformObjectUtils.isNotEmpty(boxExtent) && boxExtent.indexOf("BOX(") == 0) {
            String box = boxExtent.replace("BOX(", "").replace(")", "");
            String[] lonlatArr = box.split(",");
            String[] minLonLat = lonlatArr[0].split(" ");
            String[] maxLonLat = lonlatArr[1].split(" ");
            if (minLonLat.length == 2 && maxLonLat.length == 2) {
                lonlatList.add(Double.valueOf(minLonLat[0]));//最小经度
                lonlatList.add(Double.valueOf(minLonLat[1]));//最小纬度
                lonlatList.add(Double.valueOf(maxLonLat[0]));//最大经度
                lonlatList.add(Double.valueOf(maxLonLat[1]));//最大纬度
            }
        }

        return lonlatList;
    }

    //处理空间数据，判断存在自相交则获取修复后的空间数据，否则返回原空间数据wkt
    @Override
    public String getGeomValidWkt(String geomText) {
        String valid = isGeomValid(geomText);
        if (valid.equals("t")) {//正常
            //
        } else if (valid.equals("f")) {//自相交
            //修复空间数据自相交，获取修复后的空间数据
            geomText = makeGeomValid(geomText);
        }
        //保持空间数据类型一致性
        if (geomText.indexOf("POLYGON") == 0) {//面转多面
            geomText = "MULTIPOLYGON(" + geomText.split("POLYGON")[1] + ")";
        }
        return geomText;
    }

    //校验空间数据是否自相交
    @Override
    public String isGeomValid(String geomText) {
        String sql = "SELECT ST_IsValid(geom) FROM st_geomfromtext(?,4490) geom";

        return jdbcTemplate.queryForObject(sql, String.class, geomText);
    }

    //修复空间数据自相交，获取修复后的空间数据
    @Override
    public String makeGeomValid(String geomText) {
        String sql = "SELECT ST_AsText(ST_MakeValid(geom)) FROM st_geomfromtext(?,4490) geom";

        return jdbcTemplate.queryForObject(sql, String.class, geomText);
    }

    //判断2个空间数据是否相交
    @Override
    public boolean isGeomIntersect(String geomText1, String geomText2) {
        // 是否相交
        boolean intersects = false;
        try {
            // 工厂
            GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
            // WKTReader
            WKTReader reader = new WKTReader(geometryFactory);
            // 空间数据对象
            Geometry geom1 = reader.read(geomText1);
            // 空间数据对象
            Geometry geom2 = reader.read(geomText2);
            // 是否相交
            intersects = geom1.intersects(geom2);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return intersects;
    }

    //度转米
    public double degreeToMeter(double degree) {
        double meter = degree * (Math.PI * 2 * 6378137 / 360);

        return meter;
    }

    //米转度
    public double meterToDegree(double meter) {
        double degree = meter / (Math.PI * 2 * 6378137 / 360);

        return degree;
    }

    //计算面积
    public static double getGeomAreaByWkt(String wkt) {
        double area = 0;
        try {
            WKTReader wktReader = new WKTReader();
            //读取wkt为Geometry 几何对象
            Geometry geom = wktReader.read(wkt);
//            geom = lonlat2WebMactor(geom);// 投影转换4490->3857
            if (geom != null) {
                area = geom.getArea();
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return area;
    }

    // 投影转换->3857
    private static Geometry lonlat2WebMactor(Geometry geom) {
        Geometry res = null;
        try {
//            CoordinateReferenceSystem crsTarget = CRS.parseWKT(strWKTMercator);
            CoordinateReferenceSystem crsTarget = CRS.decode("EPSG:3857");
            // 投影转换
            MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, crsTarget);
            res = JTS.transform(geom, transform);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    public static Geometry webMercator2lonLat(Geometry geom) {
        try {
            CoordinateReferenceSystem sourceTarget = CRS.parseWKT(strWKTMercator);
            CoordinateReferenceSystem crsTarget = CRS.decode("EPSG:4490");
            MathTransform transform = CRS.findMathTransform(sourceTarget, crsTarget, true);
            //MathTransform transform = CRS.findMathTransform(sourceTarget, DefaultGeographicCRS.WGS84, true);
            return JTS.transform(geom, transform);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //获取tif文件全部数据长度--zyt
    public int getDataLengthByTIF(String tifFileName) {
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(tifFileName, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return -1;

        Band band = dataset.GetRasterBand(1);

        int xSize = dataset.getRasterXSize();
        int ySize = dataset.getRasterYSize();

        //GeoTransform 的含义：
        //六参数信息
        double[] geoTransform = dataset.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组
        //影像左上角投影坐标
        double[] luCoordinate = new double[2];
        double lon = geoTransform[0];//影像左上角横坐标：对应经度
        double lat = geoTransform[3];//影像左上角纵坐标：对应纬度
        //判断经纬度值是否正常
        if (lon < 0 || lon > 180 || lat < 0 || lat > 180) {
            return 0;
        }

        int count = 0;
        int buf[] = new int[xSize];
        for (int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for (int j = 0; j < xSize; j++) {
                //高程范围：最小值0，最大值9000，无数据值N/A
                if (buf[j] >= 0 && buf[j] <= 9000) {
                    count++;
                }
            }
        }
        dataset.delete();
//        gdal.GDALDestroyDriverManager();

        return count;
    }

    //获取tif文件全部数据值列表
    public List<Object> getAllValueListByTIF(String tifFileName) {
        List<Object> result = new ArrayList<Object>();
        List<Integer> valueList = new ArrayList<Integer>();//栅格数值列表
        List<Integer> countList = new ArrayList<Integer>();//计数列表
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(tifFileName, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return null;

        Band band = dataset.GetRasterBand(1);

        int xSize = dataset.getRasterXSize();
        int ySize = dataset.getRasterYSize();

        int buf[] = new int[xSize];
        for (int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for (int j = 0; j < xSize; j++) {
                //数值校验
                if (buf[j] >= 0 && buf[j] <= 9000) {
                    //高程范围：最小值0，最大值9000，无数据值N/A
                } else {
                    continue;
                }
                int index = valueList.indexOf(buf[j]);
                if (index == -1) {
                    valueList.add(buf[j]);
                    countList.add(1);
                } else {
                    int count = countList.get(index);
                    countList.set(index, count + 1);
                }
            }
        }
        dataset.delete();
//        gdal.GDALDestroyDriverManager();

        result.add(valueList);
        result.add(countList);

        return result;
    }

    //获取tif文件数据值
    public String getValueByTIF(String tifFileName) {
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(tifFileName, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return null;

        Band band = dataset.GetRasterBand(1);

        int xSize = dataset.getRasterXSize();
        int ySize = dataset.getRasterYSize();

        StringBuilder sb = new StringBuilder();
        int buf[] = new int[xSize];
        for (int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for (int j = 0; j < xSize; j++) {
                //数值校验
                if (buf[j] >= 0 && buf[j] <= 9000) {
                    //高程范围：最小值0，最大值9000，无数据值N/A
                } else {
                    continue;
                }
                sb.append(buf[j] + "|");
            }
        }
        String gridDataStr = sb.toString();
        gridDataStr = gridDataStr.substring(0, gridDataStr.length() - 1);
        dataset.delete();
//        gdal.GDALDestroyDriverManager();

        return gridDataStr;
    }

    //获取tif文件网格矢量数据
    public String getRectsByTIF(String tifFileName) {
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(tifFileName, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return null;
        String projection = dataset.GetProjection();//投影
        Band band = dataset.GetRasterBand(1);//选择要读取的波段数，bandNum 从 1 开始

        int xSize = dataset.getRasterXSize();//获取宽度，数组第二维，左右方向元素长度，代表经度范围
        int ySize = dataset.getRasterYSize();//获取高度，数组第一维，上下方向元素长度，代表纬度范围

        //GeoTransform 的含义：
        //六参数信息
        double[] geoTransform = dataset.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组
        //影像左上角投影坐标
        double[] luCoordinate = new double[2];
        luCoordinate[0] = geoTransform[0];//影像左上角横坐标：对应经度
        luCoordinate[1] = geoTransform[3];//影像左上角纵坐标：对应纬度
        //通常水平和垂直分辨率相等
        //遥感图像的垂直空间分辨率(经度间隔)
        double fblLon = geoTransform[1];
        //遥感图像的水平空间分辨率(纬度间隔)：
        double fblLat = geoTransform[5];
        //如果遥感影像方向没有发生旋转，即上北下南，则 geoTransA 与 geoTransB 为 0
        double geoTransA = geoTransform[2];
        double geoTransB = geoTransform[4];

        /*计算图像地理坐标：
        若图像中某一点的行数和列数分别为 row 和 column，则该点的地理坐标为：
        经度：xGeo = geoTransform[0] + row * geoTransform[1] + column * geoTransform[2]
        纬度：yGeo = geoTransform[3] + row * geoTransform[4] + column * geoTransform[5]
        */

        int count = 0;
        int buf[] = new int[xSize];
        String coordinate = "";
        StringBuilder sb = new StringBuilder();
        sb.append("MULTIPOLYGON (");
        for (int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for (int j = 0; j < xSize; j++) {
                //数值校验
                if (buf[j] >= 0 && buf[j] <= 9000) {
                    //高程范围：最小值0，最大值9000，无数据值N/A
                } else {
                    continue;
                }
                double luLon = geoTransform[0] + j * geoTransform[1] + i * geoTransform[2];
                double luLat = geoTransform[3] + j * geoTransform[4] + i * geoTransform[5];

                double ruLon = geoTransform[0] + (j + 1) * geoTransform[1] + i * geoTransform[2];
                double ruLat = geoTransform[3] + (j + 1) * geoTransform[4] + i * geoTransform[5];

                double rbLon = geoTransform[0] + (j + 1) * geoTransform[1] + (i + 1) * geoTransform[2];
                double rbLat = geoTransform[3] + (j + 1) * geoTransform[4] + (i + 1) * geoTransform[5];

                double lbLon = geoTransform[0] + j * geoTransform[1] + (i + 1) * geoTransform[2];
                double lbLat = geoTransform[3] + j * geoTransform[4] + (i + 1) * geoTransform[5];

                //coordinate = luLon + " " + luLat + "," + ruLon + " " + ruLat + "," + rbLon + " " + rbLat + "," + lbLon + " " + lbLat + "|";
                if (count > 0) {
                    coordinate = ", ";
                } else {
                    coordinate = "";
                }
                coordinate += "((" + luLon + " " + luLat + ", " + ruLon + " " + ruLat + ", " + rbLon + " " + rbLat + ", " + lbLon + " " + lbLat + ", " + luLon + " " + luLat + "))";
                sb.append(coordinate);
                count++;
                if (count % 5000 == 0) {
                    System.out.println("----count: " + count);
                }
            }
        }
        System.out.println("----count: " + count);
        sb.append(")");
        coordinate = sb.toString();
        //coordinate = coordinate.substring(0, coordinate.length() - 1);
        dataset.delete();
//        gdal.GDALDestroyDriverManager();
        return coordinate;
    }

    @Override
    public String getByGeomAndTIF(String geom, String filePath) {
        Map<String, Object> map1 = new HashMap<>();
//        map1.put("type", "clipTif");
        map1.put("type", "clipTif2");//只裁剪栅格
        // map.put("file", fileUrl);
//        String[] split = filePath.split("\\\\");
//        String layerName = split[split.length - 1].split("\\.")[0];
//         String[] split1 = filePath.split("/");
        String[] split1 = null;
        split1 = filePath.split("/");
        String layerName = split1[split1.length - 1].split("\\.")[0];
        if (layerName.contains(".tif")) {
            layerName = layerName.split(".tif")[0];
        }
        map1.put("layerName", layerName);
        String currTime = System.currentTimeMillis() + "";
//        String resultLayerName = layerName + "_裁剪_" + currTime;//裁剪结果数据集
        String resultLayerName = "temp_裁剪_" + currTime;//裁剪结果数据集
        map1.put("resultLayerName", resultLayerName);
        map1.put("geomText", geom);
        map1.put("sourceType", "dzzhTifFile");
        RestResponse serverToken = hypergraphService.getServerToken(map1);
        if (serverToken.getCode() != 200) {
            return null;
        }
        return resultLayerName;
    }

    @Override
    public Map<String, List<Map<String, String>>> getSlopeByGeomAndTIF1(String geom, String filePath) {
        Map<String, Object> map1 = new HashMap<>();
        map1.put("type", "clipTif");//裁剪栅格并导出文件发布图层
        // map.put("file", fileUrl);
//        String[] split = filePath.split("\\\\");
//        String layerName = split[split.length - 1].split("\\.")[0];
        String[] split = filePath.split("/");
        String[] split1 = split[split.length - 1].split("/");
        String layerName = split1[split1.length - 1].split("\\.")[0];
        if (layerName.contains(".tif")) {
            layerName = layerName.split(".tif")[0];
        }
        map1.put("layerName", layerName);
        String currTime = System.currentTimeMillis() + "";
//        String resultLayerName = layerName + "_裁剪_" + currTime;//裁剪结果数据集
        String resultLayerName = "temp_裁剪_" + currTime;//裁剪结果数据集
        map1.put("resultLayerName", resultLayerName);
        map1.put("geomText", geom);
        map1.put("sourceType","dzzhTifFile");
        RestResponse serverToken = hypergraphService.getServerToken(map1);
        if (serverToken.getCode() != 200) {
            return null;
        }
        String resultFileUrl = (String) serverToken.getData();//裁剪结果文件路径
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(resultFileUrl, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return null;
        Band band = dataset.GetRasterBand(1);//选择要读取的波段数，bandNum 从 1 开始

        int xSize = dataset.getRasterXSize();//获取宽度，数组第二维，左右方向元素长度，代表经度范围
        int ySize = dataset.getRasterYSize();//获取高度，数组第一维，上下方向元素长度，代表纬度范围

        //GeoTransform 的含义：
        //六参数信息
        double[] geoTransform = dataset.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组
        //影像左上角投影坐标
        double luCoordinate0 = geoTransform[0];//影像左上角横坐标：对应经度
        double luCoordinate1 = geoTransform[3];//影像左上角纵坐标：对应纬度
        //通常水平和垂直分辨率相等
        //遥感图像的垂直空间分辨率(经度间隔)
        double fblLon = geoTransform[1];
        //遥感图像的水平空间分辨率(纬度间隔)：
        double fblLat = geoTransform[5];
        //如果遥感影像方向没有发生旋转，即上北下南，则 geoTransA 与 geoTransB 为 0
        double geoTransA = geoTransform[2];
        double geoTransB = geoTransform[4];

        int count = 0;
        int buf[] = new int[xSize];
        Map<String, List<Map<String, String>>> map = new HashMap<>();
        List<Map<String, String>> objectList = null;
        Map<String, String> objects = null;
        for (int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for (int j = 0; j < xSize; j++) {
                //数值校验
                if (buf[j] < 0 && buf[j] > 90) {
                    //坡度范围：最小值0，最大值90，无数据值N/A
                    continue;
                }
                double luLon = luCoordinate0 + j * fblLon + i * geoTransA;
                double luLat = luCoordinate1 + j * geoTransB + i * fblLat;

                double ruLon = luCoordinate0 + (j + 1) * fblLon + i * geoTransA;
                double ruLat = luCoordinate1 + (j + 1) * geoTransB + i * fblLat;

                double rbLon = luCoordinate0 + (j + 1) * fblLon + (i + 1) * geoTransA;
                double rbLat = luCoordinate1 + (j + 1) * geoTransB + (i + 1) * fblLat;

                double lbLon = luCoordinate0 + j * fblLon + (i + 1) * geoTransA;
                double lbLat = luCoordinate1 + j * geoTransB + (i + 1) * fblLat;

                String coordinate = "MULTIPOLYGON (((" + luLon + " " + luLat + ", " + ruLon + " " + ruLat + ", " + rbLon +
                        " " + rbLat + ", " + lbLon + " " + lbLat + ", " + luLon + " " + luLat + ")))";
                /*if (!lawAnalysisRepository.getSTIntersects(geom, coordinate)) {
                    continue;
                }*/
                /*if (!isGeomIntersect(geom,coordinate)) {
                    continue;
                }*/
                if (map.containsKey(String.valueOf(buf[j]))) {
                    objectList = map.get(String.valueOf(buf[j]));
                } else {
                    objectList = new ArrayList<>();
                }
                objects = new HashMap<>();
                objects.put("id", UUIDGenerator.getUUID());
                objects.put("geom", coordinate);
                objectList.add(objects);
                map.put(String.valueOf(buf[j]), objectList);
                count++;
                if (count % 5000 == 0) {
                    System.out.println("----已经解析了count:{} " + count);
                }
            }
            if (count > 100000) {//test
                break;
            }
        }
        System.out.println("----总共解析了count:{} " + count);
        dataset.delete();
//        gdal.GDALDestroyDriverManager();
        return map;
    }

    @Override
    public Map<String, List<Map<String, String>>> getAspectByGeomAndTIF1(String geom, String filePath) {
        Map<String, Object> map1 = new HashMap<>();
        map1.put("type", "clipTif");//裁剪栅格并导出文件发布图层
        // map.put("file", fileUrl);
//        String[] split = filePath.split("\\\\");
//        String layerName = split[split.length - 1].split("\\.")[0];
        String[] split = filePath.split("/");
        String[] split1 = split[split.length - 1].split("/");
        String layerName = split1[split1.length - 1].split("\\.")[0];
        if (layerName.contains(".tif")) {
            layerName = layerName.split(".tif")[0];
        }
        map1.put("layerName", layerName);
        String currTime = System.currentTimeMillis() + "";
//        String resultLayerName = layerName + "_裁剪_" + currTime;//裁剪结果数据集
        String resultLayerName = "temp_裁剪_" + currTime;//裁剪结果数据集
        map1.put("resultLayerName", resultLayerName);
        map1.put("geomText", geom);
        map1.put("sourceType","dzzhTifFile");
        RestResponse serverToken = hypergraphService.getServerToken(map1);
        if (serverToken.getCode() != 200) {
            return null;
        }
        String resultFileUrl = (String) serverToken.getData();//裁剪结果文件路径
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(resultFileUrl, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return null;
        Band band = dataset.GetRasterBand(1);//选择要读取的波段数，bandNum 从 1 开始

        int xSize = dataset.getRasterXSize();//获取宽度，数组第二维，左右方向元素长度，代表经度范围
        int ySize = dataset.getRasterYSize();//获取高度，数组第一维，上下方向元素长度，代表纬度范围

        //GeoTransform 的含义：
        //六参数信息
        double[] geoTransform = dataset.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组
        //影像左上角投影坐标
        double luCoordinate0 = geoTransform[0];//影像左上角横坐标：对应经度
        double luCoordinate1 = geoTransform[3];//影像左上角纵坐标：对应纬度
        //通常水平和垂直分辨率相等
        //遥感图像的垂直空间分辨率(经度间隔)
        double fblLon = geoTransform[1];
        //遥感图像的水平空间分辨率(纬度间隔)：
        double fblLat = geoTransform[5];
        //如果遥感影像方向没有发生旋转，即上北下南，则 geoTransA 与 geoTransB 为 0
        double geoTransA = geoTransform[2];
        double geoTransB = geoTransform[4];

        int count = 0;
        int buf[] = new int[xSize];
        Map<String, List<Map<String, String>>> map = new HashMap<>();
        List<Map<String, String>> objectList = null;
        Map<String, String> objects = null;
        for (int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for (int j = 0; j < xSize; j++) {
                //数值校验
                if (buf[j] < 0 && buf[j] >= 360) {
                    //坡向范围：最小值0，最大值不超过360，无数据值N/A
                    continue;
                }
                double luLon = luCoordinate0 + j * fblLon + i * geoTransA;
                double luLat = luCoordinate1 + j * geoTransB + i * fblLat;

                double ruLon = luCoordinate0 + (j + 1) * fblLon + i * geoTransA;
                double ruLat = luCoordinate1 + (j + 1) * geoTransB + i * fblLat;

                double rbLon = luCoordinate0 + (j + 1) * fblLon + (i + 1) * geoTransA;
                double rbLat = luCoordinate1 + (j + 1) * geoTransB + (i + 1) * fblLat;

                double lbLon = luCoordinate0 + j * fblLon + (i + 1) * geoTransA;
                double lbLat = luCoordinate1 + j * geoTransB + (i + 1) * fblLat;

                String coordinate = "MULTIPOLYGON (((" + luLon + " " + luLat + ", " + ruLon + " " + ruLat + ", " + rbLon +
                        " " + rbLat + ", " + lbLon + " " + lbLat + ", " + luLon + " " + luLat + ")))";
                /*if (!lawAnalysisRepository.getSTIntersects(geom, coordinate)) {
                    continue;
                }*/
                /*if (!isGeomIntersect(geom,coordinate)) {
                    continue;
                }*/
                // 1,N;2,NE;3,E;4,ES;5,S;6,SW;7,W;8,WN
                String aspect = "";
                if (buf[j] == 0) {
                    aspect = "N";
                } else if (buf[j] >= 0 && buf[j] < 90) {
                    aspect = "NE";
                } else if (buf[j] == 90) {
                    aspect = "E";
                } else if (buf[j] >= 90 && buf[j] < 180) {
                    aspect = "ES";
                } else if (buf[j] == 180) {
                    aspect = "S";
                } else if (buf[j] >= 180 && buf[j] < 270) {
                    aspect = "SW";
                } else if (buf[j] == 270) {
                    aspect = "W";
                } else if (buf[j] >= 270 && buf[j] < 360) {
                    aspect = "WN";
                }

                if (map.containsKey(aspect)) {
                    objectList = map.get(aspect);
                } else {
                    objectList = new ArrayList<>();
                }
                objects = new HashMap<>();
                objects.put("id", UUIDGenerator.getUUID());
                objects.put("geom", coordinate);
                objectList.add(objects);
                map.put(aspect, objectList);
                count++;
                if (count % 5000 == 0) {
                    System.out.println("----已经解析了count:{} " + count);
                }
            }
            if (count > 1000000) {//test
                break;
            }
        }
        System.out.println("----总共解析了count:{} " + count);
        dataset.delete();
//        gdal.GDALDestroyDriverManager();
        return map;
    }

    @Override
    public Map<String, List<Map<String, String>>> getElevationByGeomAndTIF(String geomText, String filePath) {
        Map<String, Object> map1 = new HashMap<>();
        map1.put("type", "clipTif");//裁剪栅格并导出文件发布图层
        // map.put("file", fileUrl);
        String[] split = filePath.split("/");
//        String layerName = split[split.length - 1].split("\\.")[0];
        String[] split1 = split[split.length - 1].split("/");
        String layerName = split1[split1.length - 1].split("\\.")[0];
        if (layerName.contains(".tif")) {
            layerName = layerName.split(".tif")[0];
        }
        map1.put("layerName", layerName);
        String currTime = System.currentTimeMillis() + "";
//        String resultLayerName = layerName + "_裁剪_" + currTime;//裁剪结果数据集
        String resultLayerName = "temp_裁剪_" + currTime;//裁剪结果数据集
        map1.put("resultLayerName", resultLayerName);
        map1.put("geomText", geomText);
        map1.put("sourceType","jcsjTifFile");
        RestResponse serverToken = hypergraphService.getServerToken(map1);
        if (serverToken.getCode() != 200) {
            return null;
        }
        String resultFileUrl = (String) serverToken.getData();//裁剪结果文件路径
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(resultFileUrl, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return null;
        Band band = dataset.GetRasterBand(1);//选择要读取的波段数，bandNum 从 1 开始

        int xSize = dataset.getRasterXSize();//获取宽度，数组第二维，左右方向元素长度，代表经度范围
        int ySize = dataset.getRasterYSize();//获取高度，数组第一维，上下方向元素长度，代表纬度范围

        //GeoTransform 的含义：
        //六参数信息
        double[] geoTransform = dataset.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组
        //影像左上角投影坐标
        double luCoordinate0 = geoTransform[0];//影像左上角横坐标：对应经度
        double luCoordinate1 = geoTransform[3];//影像左上角纵坐标：对应纬度
        //通常水平和垂直分辨率相等
        //遥感图像的垂直空间分辨率(经度间隔)
        double fblLon = geoTransform[1];
        //遥感图像的水平空间分辨率(纬度间隔)：
        double fblLat = geoTransform[5];
        //如果遥感影像方向没有发生旋转，即上北下南，则 geoTransA 与 geoTransB 为 0
        double geoTransA = geoTransform[2];
        double geoTransB = geoTransform[4];

        int count = 0;
        int buf[] = new int[xSize];
        Map<String, List<Map<String, String>>> map = new HashMap<>();
        List<Map<String, String>> objectList = null;
        Map<String, String> objects = null;
        for (int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for (int j = 0; j < xSize; j++) {
                //数值校验
                if (buf[j] < 0 && buf[j] > 9000) {
                    //高程范围：最小值0，最大值9000，无数据值N/A
                    continue;
                }
                double luLon = luCoordinate0 + j * fblLon + i * geoTransA;
                double luLat = luCoordinate1 + j * geoTransB + i * fblLat;

                double ruLon = luCoordinate0 + (j + 1) * fblLon + i * geoTransA;
                double ruLat = luCoordinate1 + (j + 1) * geoTransB + i * fblLat;

                double rbLon = luCoordinate0 + (j + 1) * fblLon + (i + 1) * geoTransA;
                double rbLat = luCoordinate1 + (j + 1) * geoTransB + (i + 1) * fblLat;

                double lbLon = luCoordinate0 + j * fblLon + (i + 1) * geoTransA;
                double lbLat = luCoordinate1 + j * geoTransB + (i + 1) * fblLat;

                String coordinate = "MULTIPOLYGON (((" + luLon + " " + luLat + ", " + ruLon + " " + ruLat + ", " + rbLon +
                        " " + rbLat + ", " + lbLon + " " + lbLat + ", " + luLon + " " + luLat + ")))";
                /*if (!lawAnalysisRepository.getSTIntersects(geomText, coordinate)) {
                    continue;
                }*/
                if (!isGeomIntersect(geomText, coordinate)) {
                    continue;
                }
                //1,<0.6;2,0.6~1;3,1~1.5;4,1.5~2;5,2~2.5;6,2.5~3;7,3~3.5;8,>3.5 //km
                String elevation = "";//m
                if (buf[j] < 600) {
                    elevation = "1";
                } else if (buf[j] >= 600 && buf[j] < 1000) {
                    elevation = "2";
                } else if (buf[j] >= 1000 && buf[j] < 1500) {
                    elevation = "3";
                } else if (buf[j] >= 1500 && buf[j] < 2000) {
                    elevation = "4";
                } else if (buf[j] >= 2000 && buf[j] < 2500) {
                    elevation = "5";
                } else if (buf[j] >= 2500 && buf[j] < 3000) {
                    elevation = "6";
                } else if (buf[j] >= 3000 && buf[j] <= 3500) {
                    elevation = "7";
                } else if (buf[j] > 3500) {
                    elevation = "8";
                }

                if (map.containsKey(elevation)) {
                    objectList = map.get(elevation);
                } else {
                    objectList = new ArrayList<>();
                }
                objects = new HashMap<>();
                objects.put("id", UUIDGenerator.getUUID());
                objects.put("geom", coordinate);
                objectList.add(objects);
                map.put(elevation, objectList);
                count++;
                if (count % 5000 == 0) {
                    System.out.println("----已经解析了count:{} " + count);
                }
            }
            if (count > 1000000) {//test
                break;
            }
        }
        System.out.println("----总共解析了count:{} " + count);
        dataset.delete();
//        gdal.GDALDestroyDriverManager();
        return map;
    }
}
